在剛學會寫程式的時候,好不容易完成了一個網站系統,接著才發現如何部署與維運才是更大的問題。
一開始,我和許多人一樣,在公有雲租了一台免費主機,再透過 Nginx 做簡單的反向代理。服務確實上線了,但我也開始反覆思考幾個問題:
曾經的我為了了解這些問題,購買了一台二手伺服器,也因此而走向了維運不歸路。希望接下來的 30 天也可以把那些我踩過的坑讓大家知道不要犯相同的錯誤。
如果手上有一台伺服器,你會怎麼使用它?
最直覺的做法,可能是安裝 Proxmox VE 或是 VMware、建立幾台虛擬機,接著把需要的服務一個個放進去。需要從外面連線時,就在路由器上開幾個連接埠。需要資料庫就在內部部署一個私人資料庫。等到所有服務都能啟動、網頁也能打開,看起來就像完成了一座私有雲。
當其中一台主機失聯、資料庫主機意外斷線、VPN 帳號遭到冒用,或有人誤刪資料時,我們才會發現真正困難的問題是:
這個系列不只示範安裝步驟,也會說明每個元件解決的問題、運作原理,以及它和其他元件之間的責任邊界。接下來 30 天,我會從一台實體主機上的實驗環境開始,逐步建立 Proxmox VE、OPNsense、安全管理入口與 PostgreSQL 高可用服務,最後透過故障實驗驗證整條服務路徑。
要理解這些元件為什麼需要分工,可以先看一場真實事故。GitLab 曾發生一場同時暴露複寫、備份、告警與復原流程缺口的資料庫事故:多項保護機制看似已經存在,事故發生時卻接連失去作用。這個案例也會成為後續設計高可用、備份、監控與復原流程的共同背景。
PostgreSQL 會先把資料異動寫入預寫式日誌(Write-Ahead Log,WAL)。主要節點(Primary)負責接受寫入,待命節點(Standby)再接收並重播 WAL,讓資料副本跟上主要節點。這個過程稱為複寫(Replication)。
2017 年 1 月 31 日,GitLab.com 的待命節點因複寫落後,而且追趕資料所需的 WAL 已從主要節點移除,無法再繼續同步。當時系統也沒有把舊 WAL 另外保存成歸檔,因此工程師無法補回缺少的紀錄,只能清除待命節點的資料目錄,再使用 PostgreSQL 的 pg_basebackup 工具重新建立完整副本。
在多次嘗試重建的過程中,工程師原本準備清除待命節點的資料目錄,卻誤在主要節點上執行刪除。雖然操作在一、兩秒內就被中止,大約 300GB 的資料仍已遭到移除。這時原本可以接手服務的待命節點已先被清除,主要節點又遭到誤刪,因此複寫與故障切換(Failover)都無法救回服務。
接下來理論上應該使用備份(Backup)復原,但 GitLab 當時每日執行的 PostgreSQL 備份工具 pg_dump,使用 PostgreSQL 9.2 工具備份 PostgreSQL 9.6 資料庫,工作其實一直執行失敗。錯誤通知信又因郵件驗證設定而被拒收,導致維運人員沒有發現問題,最後檢查 S3 儲存空間時才發現裡面沒有可用的資料庫備份。
這正好顯示複寫、故障切換與備份各自處理不同問題:
pg_dump 排程存在,但產出的備份不可用
GitLab 最後只能使用事故發生約六小時前建立的 LVM 快照復原。服務雖然成功恢復,但事故前約六小時內寫入的部分資料最終無法還原。官方估計影響約 5,000 個專案、5,000 則留言與 700 個新帳號。Git 程式碼儲存庫與 Wiki 因為保存在另一套獨立系統中,沒有隨資料庫一起遺失,這也顯示分開保存不同類型的資料可以縮小事故影響範圍。
這起事件是多個保護機制同時存在缺口:待命節點正在重建、WAL 沒有歸檔、pg_dump 長期失敗、告警沒有送達、備份沒有定期還原驗證,復原流程也缺少明確的負責人。任何一項機制正常運作,都可能降低資料損失或縮短服務中斷時間。
這場事故說明,建立資料副本、執行備份、發送告警與完成復原是彼此相關、卻不能互相取代的工作。這也是本系列除了部署平台、網路與資料庫,還要分別建立故障切換、備份、監控及復原流程,最後再用故障實驗確認它們真的能運作的原因。我們要完成的不只是可以啟動的服務,而是一套發生故障或誤操作時,仍有明確處理方式的系統。
GitLab 將事故經過、失敗原因與改善項目整理在官方文章:Postmortem of database outage of January 31。
在接下來的 30 天我會從原理到實際部署安裝一步步講解,在實際部署安裝部分我也會同步在主機上進行部署。
本次會部署 PVE 叢集、OPNsense、Nginx 與 PostgreSQL 高可用架構,也會接觸網路安全、VLAN、路由、網路位址轉換(NAT)、資料庫權限與反向代理等基礎概念。你不需要事先熟悉所有技術,文章遇到相關內容時,都會先解釋它解決什麼問題、基本原理與在本次架構中的用途,再進入實際部署。
如果希望跟著本次鐵人賽一步步完成 Lab,仍建議具備基本的 Linux 操作能力,例如使用 ls、cat、mkdir、文字編輯器與 systemctl。其他需要的網路、資料庫與服務概念,則會在後續對應的篇章中逐步介紹。
我對這個系列的定位是「廣但不淺」。內容會涵蓋虛擬化、儲存、網路、安全、資料庫與監控。每項納入正文的技術,都會從基礎名詞與運作流程開始,逐步講到足以理解設計選擇與排查問題的底層原理。我也知道不是每位讀者都需要追到相同深度,有些人想完整理解技術,有些人只需要掌握完成部署所需的原理,因此可以依照自己的目標閱讀。
當然在AI如此強力的今天,你也可以選擇遇到問題時詢問AI,但是有一點需要特別注意,使用AI提供的命令與配置前我非常建議你需要知道這行命令、配置改變了甚麼。這樣即使命令使伺服器發生問題,你也能知道該從哪裡排查,並從中累積更多 Linux 經驗。
在這30天裡,我希望帶給各位的是可以與AI協作,完成一套可維護的系統並瞭解原理,而不是成為複製貼上機器人做出一個難以維護的系統。
第一天不需要瞭解太多我們先來看看接下來的30天我們可以帶來甚麼,目標是甚麼,最後可以看到的成果是甚麼。
從網路流量的角度來看,整套環境以 OPNsense 作為入口與安全邊界。內部則由 Proxmox VE(後面簡稱 PVE)承載各項虛擬機(Virtual Machine,VM),並將管理、服務、資料庫與備份網路分開。
接著,我們先以使用者角度,我們這一套系統的連線路徑。

看起來不複雜對吧?圖(一)先呈現自有環境內部的服務路徑。公開網站上線時,前方還會加入 Cloudflare,相關設定留到後續章節說明。虛擬機的維護人員或開發者會先連到跳板機,再透過 OpenSSH 的 ProxyJump 功能前往被授權的主機。需要存取私有服務的使用者則透過 OpenVPN 完成驗證並建立加密隧道,再由防火牆規則決定可以連到哪些服務。PostgreSQL 內部則透過串流複寫(Streaming Replication)維護資料副本,並由 Patroni 與 etcd 協調資料庫角色。
是不是發現前面提到的 proxy01、proxy02 與 PVE 沒有出現在圖片中?這是因為圖(一)只表示使用者如何連線到實際服務。Nginx、Keepalived 與 HAProxy 實際上會部署在 proxy01、proxy02,後面會再從 PVE 節點與 VM 放置的角度查看整體環境。
今天的重點只要先看到我們要用甚麼元件來組成系統,不用急著了解所有元件和它的使用方法後續 30 天會一一介紹每個元件的功能與配置。
這個系列有三條主線。
我們會建立三個 Proxmox VE 節點,理解:
正式架構的理想狀態,是三個 PVE 節點分別位於三台實體主機,形成真正的故障域。但為了方便講解與錄製並且讓讀者可以跟著同步操作,我這邊只使用一台實體主機進行演示,因此實際上會在一台實體PVE系統上建立三台 PVE VM。
OPNsense 會成為整套環境的網路與安全邊界,負責:
公開網頁服務則使用 Cloudflare 橘雲代理。網域仍可保留在既有註冊商,並將網域名稱的查詢工作交給 Cloudflare。瀏覽器到 Cloudflare,以及 Cloudflare 到代理伺服器虛擬機之間都使用 TLS 加密。自有環境的 TCP 443 只允許 Cloudflare 公布的來源網段進入。
但有了防火牆,不代表內部服務就自然安全。我們還會建立一台 跳板機,作為唯一公開的 SSH 管理入口。
一般維運人員只能利用 ProxyJump 前往被授權的主機,不能取得跳板機的命令列操作權限。只有專用的跳板機管理帳號可以取得 Shell,並僅用於維護跳板機本身。
資料庫部分會建立三個 PostgreSQL 節點,並逐層加入:
最終不讓應用程式直接指定 pg01、pg02 或 pg03,也就是三台 PostgreSQL 的實際服務位置,只提供兩個固定入口:
應用程式/VPN 使用者 → 資料庫讀寫 VIP → HAProxy → 主要資料庫節點
應用程式/VPN 使用者 → 資料庫唯讀 VIP → HAProxy → 次要資料庫節點
Patroni 負責資料庫角色與故障切換,HAProxy 根據 Patroni 提供的介面將流量送到正確角色,Keepalived 則負責在兩台代理伺服器之間移動 VIP。
至於誤刪資料,則透過 pgBackRest 備份、WAL 歸檔與時間點還原處理。
既然我們知道了整體上系統如何運作,那麼我們可以來從 PVE 節點的角度看整體的系統建設與相關的服務了。
看起來是不是比上一張圖還複雜?但不要怕,許多部署都是為了建立兩個以上的服務副本,像是proxy01,proxy02他們是為了在一個服務或節點出現問題時可以快速的切換。接下來 30 天每個元件也都會一一介紹,希望這 30 天可以讓各位讀者帶來真的有用的知識。
下一篇會先分清楚叢集、複寫、高可用、備份與災難復原的責任,再把這些保護目標轉成實際的硬體、虛擬機、IP、VLAN、VIP 與對外入口藍圖。完成這份部署手冊後,Day 03 才正式安裝 Proxmox VE。